package com.aaa.sys.service.impl;

import com.aaa.common.constants.CustomExceptionConstant;
import com.aaa.common.entity.Menu;
import com.aaa.common.util.CustomException;
import com.aaa.common.vo.TreeNode;
import com.aaa.sys.dao.MenuDao;
import com.aaa.sys.service.MenuService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author yuxiujie
 * @since 2021-01-19 15:19:53
 */
@Service("menuService")
public class MenuServiceImpl implements MenuService {
    @Resource
    private MenuDao menuDao;

    /**
     * 通过ID查询单条数据
     *
     * @param menuId 主键
     * @return 实例对象
     */
    @Override
    public Menu queryById(Integer menuId) {
        if (menuId==null||menuId<=0){
            throw new CustomException(CustomExceptionConstant.ID_NOT_NULL.getErrorCode(),
                    CustomExceptionConstant.ID_NOT_NULL.getErrorMessage());
        }
        return this.menuDao.queryById(menuId);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<Menu> queryAllByLimit(int offset, int limit) {
        return this.menuDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param menu 实例对象
     * @return 实例对象
     */
    @Override
    public Menu insert(Menu menu) {
        this.menuDao.insert(menu);
        return menu;
    }

    /**
     * 修改数据
     *
     * @param menu 实例对象
     * @return 实例对象
     */
    @Override
    public Menu update(Menu menu) {
        menu.setUpdateBy("admin");
        menu.setUpdateTime(new Date());
        this.menuDao.update(menu);
        return this.queryById(menu.getMenuId());
    }

    /**
     * 通过主键删除数据
     *
     * @param menuId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer menuId) {
        return this.menuDao.deleteById(menuId) > 0;
    }

    /**
     * 查询多条数据
     *
     * @param menu Menu
     * @return 对象列表
     */
    @Override
    public List<Menu> queryAll(Menu menu) {
        List<Menu> menus = this.menuDao.queryAll(menu);
        List<Menu> menuList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(menus)){
            //获取一级菜单
            for (Menu  menu1 : menus) {
                if (menu1.getParentId()==0){
                    menu1.setValue(menu1.getMenuId());
                    menu1.setLabel(menu1.getMenuName());
                    menuList.add(menu1);
                    //查找一级菜单的孩子
                    bindMenuChildren(menu1,menus);
                }
            }
        }
        return menuList;
    }
    private void bindMenuChildren(Menu currentMenu,List<Menu> menus){
        for (Menu menu : menus) {
            //判断循环节点的父节点ID是否和当前节点相等，如果相等，说明循环节点是当前节点的子节点
            if (menu.getParentId().equals(currentMenu.getMenuId())) {
                //获取当前节点的所有孩子 如果是第一个孩子 获取集合为空
                List<Menu> children = currentMenu.getChildren();
                if (children == null) {
                    children = new ArrayList<>();
                }
                menu.setValue(menu.getMenuId());
                menu.setLabel(menu.getMenuName());
                children.add(menu);
                //再次设置孩子集合
                currentMenu.setChildren(children);
                //自己调自己，为当前循环节点继续找孩子
                bindMenuChildren(menu, menus);
            }
        }
    }
    @Override
    public List<TreeNode> queryAllMenuTree() {
        //获取所有数据
        List<TreeNode> treeNodes = menuDao.queryAllMenuTree();
        //在定义个新的集合，用户拼装返回后的数据
        List<TreeNode> treeNodeList = new ArrayList<>();
        //判断获取数据是否为空
        if (!CollectionUtils.isEmpty(treeNodes)){
            //获取一级菜单
            for (TreeNode treeNode : treeNodes) {
                if (treeNode.getParentId()==0){
                    treeNodeList.add(treeNode);
                    //查找一级菜单的孩子
                    bindChildren(treeNode,treeNodes);
                }
            }
        }
        return treeNodeList;
    }

    /**
     * 功能描述:递归从集合中查找当前节点的子节点
     * @param currentNode TreeNode
     * @param treeNodes List<TreeNode>
     * @return void 无返回值
     */
    private void bindChildren(TreeNode currentNode,List<TreeNode> treeNodes){
        for (TreeNode treeNode : treeNodes) {
            //判断循环节点的父节点ID是否和当前节点相等，如果相等，说明循环节点是当前节点的子节点
            if (treeNode.getParentId()==currentNode.getId()){
                //获取当前节点的所有孩子 如果是第一个孩子 获取集合为空
                List<TreeNode> children = currentNode.getChildren();
                if(children==null){
                    children = new ArrayList<>();
                }
                children.add(treeNode);
                //再次设置孩子集合
                currentNode.setChildren(children);
                //自己调自己，为当前循环节点继续找孩子
                bindChildren(treeNode,treeNodes);
            }
        }
    }

    @Override
    public List<TreeNode> queryMenuTreeByUserId(int userId) {
        //获取所有数据
        List<TreeNode> treeNodes = menuDao.queryMenuTreeByUserId(userId);
        //在定义个新的集合，用户拼装返回后的数据
        List<TreeNode> treeNodeList = new ArrayList<>();
        //判断获取数据是否为空
        if (!CollectionUtils.isEmpty(treeNodes)){
            //获取一级菜单
            for (TreeNode treeNode : treeNodes) {
                if (treeNode.getParentId()==0){
                    treeNodeList.add(treeNode);
                    //查找一级菜单的孩子
                    bindChildren(treeNode,treeNodes);
                }
            }
        }
        return treeNodeList;
    }

    @Override
    public List<Menu> queryUrlIsNotNull() {
        Menu menu = new Menu();
        menu.setUrl("notNull");
        menu.setVisible('0');
        return menuDao.queryAll(menu);
    }

    @Override
    public Integer[] queryMenuIdForTreeByRoleId(int roleId) {
        return menuDao.queryMenuIdForTreeByRoleId(roleId);
    }

    @Override
    public List<Menu> checkRoleName(Integer menuId, String menuName, Integer parentId) {
        return this.menuDao.checkRoleName(menuId, menuName,parentId);
    }
}